export default function (config) {
  const { replaceFields } = config;

  const RF = {
    ...{
      key: "key",
      title: "title",
      children: "children"
    },
    ...replaceFields
  };

  return {
    data() {
      return {
        replaceFields,
        treeData: [],
        dataList: [],
        searchValue: "",
        autoExpandParent: true,
        expandedKeys: [],
        currentItem: null
      };
    },
    methods: {
      formatData(sourceData, currentKey) {
        this.treeData = this.formatTreeData(sourceData);
        this.dataList = this.generateList(sourceData);
        if (currentKey) {
          this.currentItem = this.findNode(currentKey, this.treeData);
          this.initExpandedKeys(currentKey);
        } else {
          if (this.treeData.length > 0) {
            this.currentItem = this.treeData[0];
            this.expandedKeys = [];
          } else {
            this.currentItem = null;
            this.expandedKeys = [];
          }
        }
      },
      findNode(targetKey, tree) {
        let target;
        for (let i = 0; i < tree.length; i++) {
          const node = tree[i];
          if (node[RF.key] === targetKey) {
            target = node;
            break;
          }
          if (node[RF.children]) {
            const res = this.findNode(targetKey, node[RF.children]);
            if (res) {
              target = res;
              break;
            }
          }
        }
        return target;
      },
      initExpandedKeys(targetKey) {
        const expandedKeys = this.dataList
          .map((item) => {
            if (item[RF.key] === targetKey) {
              return this.getParentKey(targetKey, this.treeData);
            }
            return null;
          })
          .filter((item, i, self) => item && self.indexOf(item) === i);
        this.expandedKeys = expandedKeys;
      },
      onExpand(expandedKeys) {
        this.expandedKeys = expandedKeys;
        this.autoExpandParent = false;
      },
      getParentKey(key, tree) {
        let parentKey;
        for (let i = 0; i < tree.length; i++) {
          const node = tree[i];
          if (node[RF.children]) {
            if (node[RF.children].some((item) => item[RF.key] === key)) {
              parentKey = node[RF.key];
            } else if (this.getParentKey(key, node[RF.children])) {
              parentKey = this.getParentKey(key, node[RF.children]);
            }
          }
        }
        return parentKey;
      },
      generateList(tree) {
        const dLst = [];
        const gl = (data) => {
          for (let i = 0; i < data.length; i++) {
            const node = data[i];
            dLst.push({
              [`${RF.key}`]: node[RF.key],
              [`${RF.title}`]: node[RF.title]
            });
            if (node[RF.children]) {
              gl(node[RF.children]);
            }
          }
        };
        gl(tree);
        return dLst;
      },
      onSearchChange(e) {
        const value = e.target.value;
        const expandedKeys = this.dataList
          .map((item) => {
            if (item[RF.title].indexOf(value) > -1) {
              return this.getParentKey(item[RF.key], this.treeData);
            }
            return null;
          })
          .filter((item, i, self) => item && self.indexOf(item) === i);
        Object.assign(this, {
          expandedKeys,
          searchValue: value,
          autoExpandParent: true
        });
      },
      formatTreeData(tree) {
        if (!tree) {
          return [];
        }
        return tree.map((item) => ({
          ...item,
          [`${RF.children}`]: this.formatTreeData(item[RF.children]),
          scopedSlots: {
            title: "custom"
          }
        }));
      }
    }
  };
}
